package com.binance.gateway.util;

import com.binance.gateway.ua.CachingParser;
import com.binance.gateway.ua.Client;
import com.binance.master.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;

/**
 * Created by Fei.Huang on 2019/1/15.
 */
@Slf4j
public class UserAgentUtil {

    private static CachingParser uaParser;
    private static UserAgentUtil instance = null;

    private UserAgentUtil() {
        uaParser = new CachingParser();
    }

    private static UserAgentUtil getInstance() {
        if (instance == null) {
            synchronized (UserAgentUtil.class) {
                if (instance == null)
                    instance = new UserAgentUtil();
            }
        }
        return instance;
    }

    public static boolean illegalUserAgent(String clientType, String userAgentString) {

        try {

            if (!ignoreSpecialClients(clientType, userAgentString)) {

                Client client = getInstance().uaParser.parse(userAgentString);
                if (null != client) {
                    String userAgentFamily = client.userAgent.family;
                    String osFamily = client.os.family;
                    String deviceFamily = client.device.family;
                    log.info("UserAgentFamily:{}, OSFamily:{}, DeviceFamily:{}", userAgentFamily, osFamily, deviceFamily);
                    return isIllegal(osFamily, deviceFamily);
                } else {
                    log.warn("UserAgentUtil client is null");
                    return true;
                }

            } else {

                return false;
            }

        } catch (Exception e) {
            log.error("illegalUserAgent error", e);
            return true;
        }

    }

    // 当操作系统和设备无法都为other时，判定为非法UserAgent
    private static boolean isIllegal(String osFamily, String deviceFamily) {
        return isOther(osFamily) && isOther(deviceFamily);
    }

    private static boolean isOther(String flag) {
        return "other".equalsIgnoreCase(flag);
    }

    /**
     * 是否为可忽略的情况
     *
     * @param clientType
     * @param userAgent
     * @return
     */
    private static boolean ignoreSpecialClients(final String clientType, final String userAgent) {
        return isLegalAndroidUserAgent(clientType, userAgent) || isLegalPcUserAgent(clientType, userAgent);
    }

    /**
     * clientTYpe为android, userAgent为okhttp时，不校验
     *
     * @param clientType
     * @param userAgent
     * @return
     */
    private static boolean isLegalPcUserAgent(final String clientType, final String userAgent) {
        return ("android".equalsIgnoreCase(clientType) || "androidinfo".equalsIgnoreCase(clientType)) && StringUtils.isNotBlank(userAgent) && userAgent.contains("okhttp");
    }

    /**
     * clientTYpe为pc, userAgent为空或-时，不校验
     *
     * @param clientType
     * @param userAgent
     * @return
     */
    private static boolean isLegalAndroidUserAgent(final String clientType, final String userAgent) {
        return "pc".equalsIgnoreCase(clientType) && (StringUtils.isBlank(userAgent) || "-".equalsIgnoreCase(userAgent) || "null".equalsIgnoreCase(userAgent));
    }
}